﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.Security.Principal;
using System.Threading;
using System.Windows.Forms;
using System.Runtime.Remoting.Messaging;
using FscNET.Apm;
using System.IO;
using FscNET.NamedPipes;
using System.Text;

//using Wintellect.Threading.AsyncProgModel;

namespace FscNET.Client
{
    public sealed partial class Main : Form
    {
        //iba test
        //private PipeClient _client;
        private NamedPipeClientStream _clientStream;
        private static readonly ASCIIEncoding encoder = new ASCIIEncoding();
        private FMask _overlay;
        private Overlay _overlayDeleg;
        private AsyncEnumerator _ae;

        public Main()
        {
            InitializeComponent();
            Load += Form_Load;
            Shown += Form_Shown;
            Text = Program.ProductTitle; //+ " (kernel " + Program.RT.GetVersion() + ")";

            _overlayDeleg = CreateOverlay;
            //tsbtnTest.Click += Test;
            _ae = new AsyncEnumerator();
        }

        private void CreateClientStream()
        {
            if(_clientStream != null) _clientStream.Dispose();
            _clientStream=new NamedPipeClientStream(
                ".",
                "CooTracePipe",
                PipeDirection.Out,
                PipeOptions.Asynchronous | PipeOptions.WriteThrough,
                TokenImpersonationLevel.None,
                HandleInheritability.None
                );
        }

        private IEnumerator<int> BootCooKernel(AsyncEnumerator ae)
        {
            ShowOverlay("Spúšťam kernel...");
            string kernel_ver = null;
            //Thread.Sleep(5000);
            ((Action)delegate { 
                //kernel_ver = Program.RT.GetVersion().ToString(CultureInfo.InvariantCulture); 
                Thread.Sleep(500); 
            }).BeginInvoke(ae.End(), null);
            yield return 1;
            statlblKernelVersion.Text += kernel_ver;
            HideOverlay();
            yield return 1;
            _ae = null;
        }

        private void Form_Load(object sender, EventArgs e)
        {
            
        }

        private void Form_Shown(object sender, EventArgs e)
        {
            _ae.BeginExecute(BootCooKernel(_ae), _ae.EndExecute, null);

            //System.Threading.Thread.Sleep(2000);
            //_overlay.Close();
            //ShowOverlay("Spúšťam kernel...");
            //string kernel_ver = null;
            //((Action)delegate {
            //    kernel_ver = Program.RT.GetVersion().ToString();
            //}).BeginInvoke(delegate(IAsyncResult ar)
            //{
            //    ((Action)((AsyncResult)ar).AsyncDelegate).EndInvoke(ar);
            //    Invoke((Action)delegate { statlblKernelVersion.Text += kernel_ver; });
            //    HideOverlay();
            //}, null);
            
        }
        private void CreateOverlay(string message)
        {
            _overlay = new FMask(message, this);
            _overlay.Show(this);
        }
        private void ShowOverlay(string message)
        {
            if (InvokeRequired)
            {
                Invoke(_overlayDeleg, message);
            }
            else
                _overlayDeleg(message);
        }
        private void HideOverlay()
        {
            if (InvokeRequired)
            {
                Invoke((Action)delegate { _overlay.Close(); });
            }
            else
                _overlay.Close();
        }
        private void Test(object sender, EventArgs e)
        {
            ShowOverlay("TEST");
            ((Action)delegate
            {
                Thread.Sleep(3000);
            }).BeginInvoke(delegate(IAsyncResult ar)
            {
                ((Action)((System.Runtime.Remoting.Messaging.AsyncResult)ar).AsyncDelegate).EndInvoke(ar);
                HideOverlay();
            }, null);
        }

        private void tsbtnTest_Click(object sender, EventArgs e)
        {
            if(_clientStream == null)
            {
                CreateClientStream();
                if (_clientStream == null) return;
            }
            if(!_clientStream.IsConnected)
            {
                _clientStream.Connect(0); //necakaj na spustenie servera
                if(!_clientStream.IsConnected) return;
            }
            
            //if (_client == null)
            //{
            //    _client = new PipeClient("CooTracePipe");
            //    _client.Connect();
            //}
            //if (!_client.CheckConnection()) return;
            foreach (string line in File.ReadAllLines(@"..\..\..\trace_sample.txt"))
            {
                //_client.SendMessage(line + "\0");
                try
                {
                    _clientStream.Write(encoder.GetBytes(line + "\0"));
                }
                catch (IOException)
                {
                    if(_clientStream.State == PipeState.Broken) //server bol zatvoreny
                        _clientStream.Connect(0);
                    if (_clientStream.State != PipeState.Connected) return;
                    try
                    {
                        _clientStream.Write(encoder.GetBytes(line + "\0"));
                    }
                    catch
                    {
                        return;
                    }
                }
            }
        }
    }

    public delegate void Action();

    public delegate void Overlay(string message);
}
